package com.ideal.hadoopadmin.web.controller;

import com.ideal.hadoopadmin.framework.message.WebMessage;
import com.ideal.hadoopadmin.framework.message.WebMessageLevel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.ui.Model;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by CC on 2016/2/16.
 */
public abstract class UIController {
    public void saveError(Model model, String error) {
        add(model, "global_error", new WebMessage(error, WebMessageLevel.ERROR));
    }

    public void saveMessage(Model model, String message) {
        add(model, "global_message", new WebMessage(message, WebMessageLevel.INFO));
    }

    public void saveSuccess(Model model, String message) {
        add(model, "global_success", new WebMessage(message, WebMessageLevel.SUCCESS));
    }

    protected void add(Model model, String key, WebMessage message) {
        List<WebMessage> list = new ArrayList<WebMessage>();
        if (model.containsAttribute(key)) {
            list = (List<WebMessage>) model.asMap().get(key);
        }
        list.add(message);
        if (model instanceof RedirectAttributes) {
            ((RedirectAttributes) model).addFlashAttribute(key, list);
        } else {
            model.addAttribute(key, list);
        }
    }

    protected void doInitBinder(HttpServletRequest requst, ServletRequestDataBinder binder) {
    }

    public abstract String getPortalPrefix();

    protected String redirect(String path) {
        String portalName = getPortalPrefix();
        if (portalName.startsWith("/")) {
            return "redirect:" + portalName + path;
        }
        return "redirect:/" + portalName + path;
    }

    protected String forward(String path) {
        String portalName = getPortalPrefix();
        if (portalName.startsWith("/")) {
            return "forward:" + portalName + path;
        }
        return "forward:/" + portalName + path;
    }

    protected PageRequest buildPageRequest(HttpServletRequest request) {
        return buildPageRequest(request, 10);
    }

    protected PageRequest buildPageRequest(HttpServletRequest request, int pageSize) {
        int pageno = 0;
        try {
            pageno = Integer.parseInt(request.getParameter("page")) - 1;
        } catch (Exception e) {
            pageno = 0;
        }
        //默认30页
        return new PageRequest(pageno, pageSize);
    }

    protected PageRequest buildPageRequest(HttpServletRequest request, Sort sort) {
        return buildPageRequest(request, 10, sort);
    }

    protected PageRequest buildPageRequest(HttpServletRequest request, int pageSize, Sort sort) {
        int pageno = 0;
        try {
            pageno = Integer.parseInt(request.getParameter("page")==null?"1":request.getParameter("page")) - 1;
        } catch (Exception e) {
            pageno = 0;
        }
        //默认30页
        return new PageRequest(pageno, pageSize, sort);
    }

    /**
     * 获取访问者IP
     *
     * 在一般情况下使用Request.getRemoteAddr()即可，但是经过nginx等反向代理软件后，这个方法会失效。
     *
     * 本方法先从Header中获取X-Real-IP，如果不存在再从X-Forwarded-For获得第一个IP(用,分割)，
     * 如果还不存在则调用Request .getRemoteAddr()。
     *
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) throws Exception{
        String ip = request.getHeader("X-Real-IP");
        if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip;
        }
        ip = request.getHeader("X-Forwarded-For");
        if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个IP值，第一个为真实IP。
            int index = ip.indexOf(',');
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        } else {
            return request.getRemoteAddr();
        }
    }
}
